package uk.co.revisual.domino.core
{
	import org.puremvc.as3.multicore.patterns.observer.Notifier;
	import org.puremvc.as3.multicore.utilities.statemachine.StateMachine;
	
	import uk.co.revisual.creation.DynamicClassFactory;
	import uk.co.revisual.domino.consts.DominoConsts;
	import uk.co.revisual.domino.controller.cmaps.DominoCmdMap;
	import uk.co.revisual.domino.injectors.DominoInjector;
	import uk.co.revisual.domino.proxies.FSMModelProxy;

	public class FSMFacade extends Notifier
	{
		/**
		 *@private 
		 */
		private var _stateMachine:StateMachine;
		
		/**
		 *@private 
		 */
		private var _fsmModel:FSMModel;
		
		/**
		 *@private 
		 */
		private var _fsmHistory:FSMHistory;
		
		/**
		 *@private 
		 */
		private var _fsmClassFactory:DynamicClassFactory;
		
		/**
		 * A reference to the StateMachine 
		 */
		public function get stateMachine():StateMachine{
			if( _stateMachine == null ) _stateMachine = StateMachine( facade.retrieveMediator( DominoConsts.MEDIATOR_NAMES.STATE_MACHINE ) );
			return _stateMachine;
		}
		
		/**
		 * A reference to the FSMModel
		 */
		public function get model():FSMModel{
			if( _fsmModel == null ) _fsmModel = FSMModelProxy( facade.retrieveProxy( DominoConsts.PROXY_NAMES.FSM_MODEL_PROXY ) );
			return _fsmModel;
		}
		
		/**
		 * A reference to the FSMHistory
		 */
		public function get history():FSMHistory{
			if( _fsmHistory == null ) _fsmHistory = FSMHistory( facade.retrieveProxy( DominoConsts.PROXY_NAMES.FSM_HISTORY_PROXY ) );
			return _fsmHistory;
		}
		
		/**
		 * A reference to the factory containing the ICommand and State Classes 
		 */
		public function get factory():DynamicClassFactory{
			if( _fsmClassFactory == null ) _fsmClassFactory = DynamicClassFactory( facade.retrieveProxy( DominoConsts.PROXY_NAMES.FSM_CLASS_FACTORY_PROXY ) );
			return _fsmClassFactory;
		}
		
		/**
		 * injects the FSM into the framework 
		 * @param fsm the xml markup
		 * @param cmdClasses any ICommand Classes referred to in the xml markup
		 * @param stateClasses any subclasses of the State class referred to in the xml markup
		 * 
		 */
		public function inject( fsm:XML, cmdClasses:Array, stateClasses:Array = null ):void{
			var injector:DominoInjector = new DominoInjector( fsm, cmdClasses.concat( stateClasses ) );
			injector.initializeNotifier( multitonKey );
		}
		
		/**
		 * unregisters all FSM actors from the framework, and destroys local refs.
		 */
		public function destroy():void{
			
			// remove fsm actors
			facade.removeMediator(StateMachine.NAME);
			facade.removeProxy( DominoConsts.PROXY_NAMES.FSM_MODEL_PROXY );
			facade.removeProxy( DominoConsts.PROXY_NAMES.FSM_HISTORY_PROXY );
			facade.removeProxy( DominoConsts.PROXY_NAMES.FSM_CLASS_FACTORY_PROXY );
			
			_stateMachine = null;
			_fsmModel = null;
			_fsmHistory = null;
			_fsmClassFactory = null;
			
			// removes all commands
			var cmap:DominoCmdMap = new DominoCmdMap();
			cmap.initializeNotifier( multitonKey );
			cmap.vacate();
		}
		
	}
}